﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.MemoryMappedFiles;

namespace SharedMemoryExplorer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        
        public MainWindow()
        {
            InitializeComponent();
        }

        private void openMem_Click(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(new Action(watchMem), null);
        }

        private void writeMemory_Click(object sender, RoutedEventArgs e)
        {
            string memContent = this.memConatentWrite.Text;
            byte[] writeData = hexstringToBytes(memContent);
            if (writeData == null)
            {
                MessageBox.Show("输入有误，输入的值只能为十六进制整字节，可以有空格");
                return;
            }
            int memSize = 0;
            try
            {
                memSize = int.Parse(this.memSizeInput.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("输入的内存大小只能为数字");
                return;
            }
            using (var mmf = MemoryMappedFile.CreateOrOpen(this.memNameinput.Text, memSize))
            {
                var accessor = mmf.CreateViewAccessor();
                accessor.WriteArray<byte>(0, writeData, 0, writeData.Length);
            }
        }
        private async void watchMem()
        {
            int dataLength = 0;
            try
            {
                dataLength = int.Parse(this.memSizeInput.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("输入的内存大小只能为数字");
                return;
            }
            using (var mmf = MemoryMappedFile.CreateOrOpen(this.memNameinput.Text, dataLength))
            {
                var accessor = mmf.CreateViewAccessor();
                byte[] memContent = new byte[dataLength];
                accessor.ReadArray<byte>(0, memContent, 0, memContent.Length);
                while (true)
                {
                    this.memContentShow.Text = byteToStyledString(memContent);
                    await Task.Run(() =>
                    {
                        byte[] currentContent = new byte[dataLength];
                        while (true)
                        {
                            Thread.Sleep(10);
                            accessor.ReadArray<byte>(0,currentContent, 0, currentContent.Length);
                            if (Enumerable.SequenceEqual(memContent, currentContent))
                                continue;
                            else
                            {
                                memContent = currentContent;
                                break;
                            }
                        }
                    });
                    
                }
            }
        }

        private byte[] hexstringToBytes(string hexStr)
        {
            hexStr = hexStr.Replace(" ", "");
            if (hexStr.Length % 2 != 0)
            {
                return null;
            }
            byte[] res = new byte[hexStr.Length / 2];
            try
            {
                for (int i = 0; i < hexStr.Length / 2; i++)
                {
                    res[i] = Convert.ToByte(hexStr.Substring(i * 2, 2), 16);
                }
                return res;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private string byteToStyledString(byte[] data)
        {
            string res = "";
            foreach (byte b in data)
            {
                if (b <= 0x0f)
                    res += "0" + String.Format("{0:x}", b) + " ";
                else
                    res += String.Format("{0:x}", b) + " ";
            }
            return res;
        }


    }
}
